/*
 * Copyright (c) 2024 Black Sesame Technologies
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <type_traits>
#include "dal_msg/dalidl_runtime_cpp/traits.hpp"
#include "dalidl_typesupport_cpp/message_type_support.hpp"
#include "dalidl_typesupport_introspection_cpp/message_introspection.hpp"
#include "MessageTypeSupport.hpp"

template <typename MessageT>
constexpr
	typename std::enable_if_t<
		dalidl_generator_traits::is_message<MessageT>::value,
		const dalidl_message_type_support_t &>
	get_message_type_support_handle()
{
	auto handle = dalidl_typesupport_cpp::get_message_type_support_handle<MessageT>();
	if (!handle)
	{
		throw std::runtime_error("Type support handle unexpectedly nullptr");
	}
	return *handle;
}


using MessageTypeSupport_c =
  dal_cyclonedds_cpp::MessageTypeSupport<dalidl_typesupport_introspection_c__MessageMembers>;
using MessageTypeSupport_cpp =
  dal_cyclonedds_cpp::MessageTypeSupport<dalidl_typesupport_introspection_cpp::MessageMembers>;


bool is_type_self_contained(const dalidl_message_type_support_t * type_supports)
{
  auto ts = get_message_typesupport_handle(
    type_supports,
    dalidl_typesupport_introspection_cpp::typesupport_identifier);
  if (ts != nullptr) {   // CPP typesupport
    auto members = static_cast<const dalidl_typesupport_introspection_cpp::MessageMembers *>(
      ts->data);
    MessageTypeSupport_cpp mts(members);
    return mts.is_type_self_contained();
  } else {
    ts = get_message_typesupport_handle(
      type_supports,
      dalidl_typesupport_introspection_c__identifier);
    if (ts != nullptr) {  // C typesupport
      auto members = static_cast<const dalidl_typesupport_introspection_c__MessageMembers *>(
        ts->data);
      MessageTypeSupport_c mts(members);
      return mts.is_type_self_contained();
    } else {
      DAL_SET_ERROR_MSG("Non supported type-supported");
      return false;
    }
  }
}